package com.ahui.util;

import com.ahui.domain.ResultDataFGKDZ;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.springframework.http.MediaType;
import org.apache.commons.io.IOUtils;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

/**
 * @author : ph.li
 * @date : 2023/7/30 13:16
 */
@Slf4j
public class FileUtil {

    /**
     * 获取文件夹下的所有文件
     * @param inputPath  输入路径
     * @return
     */
    public static List<File> getFiles(String inputPath) {
        List<File> files = new ArrayList<>();
        File filefloder = new File(inputPath);
        File[] allTypeFiles = filefloder.listFiles();
        assert files != null;
        for (File file : allTypeFiles){
            if (file.isDirectory())
                return getFiles(file.getPath());
            files.add(file);

        }
        return files;
    }

    /**
     * 获取文件夹下的所有一级子目录
     * @param inputPath 输入路径
     * @return
     */
    public static List<File> getfilefloders(String inputPath) {
        List<File> files = new ArrayList<>();
        File filefloder = new File(inputPath);
        File[] allTypeFiles = filefloder.listFiles();
        assert files != null;
        for (File file : allTypeFiles){
            if (file.isDirectory())
                files.add(file);

        }
        return files;
    }

    /**
     * 判断文件是否为pdf文件
     * @param file
     * @return
     */
    public static boolean isPdfFile(File file) {
        try (InputStream inputStream = Files.newInputStream(file.toPath()))  {
            byte[] data = new byte[4];
            inputStream.read(data);
            String str = new String(data);
            if (str.equals("%PDF")) {
                return true;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 判断文件是否为tiff文件
     * @param file
     * @return
     */
    public static boolean isTifFile(File file) {
        try (InputStream inputStream = Files.newInputStream(file.toPath())) {
            byte[] buffer = new byte[4];
            inputStream.read(buffer);// 读取文件头部4个字节
// 判断是否是tif文件
            if(buffer[0] == 'I' && buffer[1] == 'I' && buffer[2] == '*' && buffer[3] == '\0'
                    || buffer[0] == 'M' && buffer[1] == 'M' && buffer[2] == '\0' && buffer[3] == '*'){
                 return true;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 判断文件是否为word文件
     * @param file
     * @return
     */
    public static boolean isWordFile(File file) {
        try(InputStream inputStream = Files.newInputStream(file.toPath())) {
            byte[] bytes = new byte[8];
            inputStream.read(bytes);
            if (bytes[0] == (byte) 0xD0 && bytes[1] == (byte) 0xCF && bytes[2] == (byte) 0x11 && bytes[3] == (byte) 0xE0
                    && bytes[4] == (byte) 0xA1 && bytes[5] == (byte) 0xB1 && bytes[6] == (byte) 0x1A && bytes[7] == (byte) 0xE1) {
                return true;
            } else if (bytes[0] == (byte) 0x50 && bytes[1] == (byte) 0x4B && bytes[2] == (byte) 0x03 && bytes[3] == (byte) 0x04
                    && bytes[4] == (byte) 0x14 && bytes[5] == (byte) 0x00 && bytes[6] == (byte) 0x06 && bytes[7] == (byte) 0x00) {
                return true;
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return false;
    }

    /**
     * 判断文件是否是excel文件
     * @param file
     * @return
     */
    public static boolean isExcel(File file){
        try(InputStream inputStream = Files.newInputStream(file.toPath())) {
            byte[] firstBytes = new byte[8];
            if (inputStream.read(firstBytes) != -1 && (checkBiffHeader(firstBytes) || checkOOXMLHeader(firstBytes))) {
                    return true;

            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return false;
    }

    /**
     * 文件类型转换  file 转换为  MultiparFile
     * @param file
     * @return
     */
    public static MultipartFile file2MultipartFile(File file) {
        FileItem item = new DiskFileItemFactory().createItem("file"
                , MediaType.MULTIPART_FORM_DATA_VALUE
                , true
                , file.getName());
        try (InputStream input = Files.newInputStream(file.toPath());
             OutputStream os = item.getOutputStream()) {
            // 流转移
            IOUtils.copy(input, os);
        } catch (Exception e) {

        }

        return new CommonsMultipartFile(item);
    }

    /**
     * 将文件转换为base64
     * @param filePath
     * @return
     */
    public static String fileToBase64(String filePath) {
        Path path = Paths.get(filePath);
        File file = path.toFile();
        if (!file.exists() || file.isDirectory()) {
            return null;
        }
        try {
            byte[] bytes = Files.readAllBytes(path);
            return Base64.getEncoder().encodeToString(bytes);
        }catch (Exception e){
            //log.info("文件转base64 异常：" + e);
            return null;
        }
    }

    /**
     * 读取properties配置文件
     * @param fileName resources下的文件的文件名
     * @return
     */
    public static Map<String,String> getProperties(String fileName){
        Map<String,String> map = new HashMap<>();
        InputStream is = null;
        try {
            is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
        }catch (Exception e) {
            log.error("配置文件{}不存在!\n" + e ,fileName);
//            throw new BizRuntimeException("配置文件不存在!");
        }
        if (is == null) {
            log.warn("未读取到配置文件的内容!");
            return null;
        }
        BufferedReader bf = new BufferedReader(new InputStreamReader(is));
        Properties ps = new Properties();
        try {
            ps.load(bf);
            is.close();
            bf.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        Enumeration mappingPropertiesEenumeration = ps.propertyNames();
        while (mappingPropertiesEenumeration.hasMoreElements()) {
            String key = (String) mappingPropertiesEenumeration.nextElement();
            String value = ps.getProperty(key);
            map.put(key, value);
        }
        return map;
    }

    /**
     * 去除文件名后缀
     * @param fileName
     * @return
     */
    public static String RemoveFileSuffix (String fileName) {
        if (fileName.lastIndexOf(".") != -1) {
            fileName = fileName.substring(0, fileName.lastIndexOf("."));
        }
        return fileName;
    }

    /**
     * 获取文件名不加后缀
     * @param filePath
     * @return
     */
    public static String getFileNameNoExtName(String filePath) {
        if (filePath == null) {
            return null;
        } else {
            int len = filePath.lastIndexOf(".");
            int sta = filePath.lastIndexOf(File.separator);
            if (len > 0) {
                filePath = filePath.substring((sta + 1), len);
            }
            return filePath;
        }
    }

    /**
     * 获取文件拓展名
     * @param fileName
     * @return
     */
    public static String getFileExt(String fileName) {
        return fileName != null && fileName.indexOf(".") > 0 ? fileName.substring(fileName.lastIndexOf(".") + 1) : "";
    }



    // excel工具类
    private static boolean checkBiffHeader(byte[] header) {
        return header[0] == (byte) 0xD0 && header[1] == (byte) 0xCF && header[2] == (byte) 0x11 && header[3] == (byte) 0xE0
                && header[4] == (byte) 0xA1 && header[5] == (byte) 0xB1 && header[6] == (byte) 0x1A && header[7] == (byte) 0xE1;
    }

    //excel工具类
    private static boolean checkOOXMLHeader(byte[] header) {
        return header[0] == (byte) 0x50 && header[1] == (byte) 0x4B && header[2] == (byte) 0x03 && header[3] == (byte) 0x04
                && header[4] == (byte) 0x14 && header[5] == (byte) 0x00 && header[6] == (byte) 0x06 && header[7] == (byte) 0x00;
    }



    // 解析结果
    public static ResultDataFGKDZ analysisResult(File f, JSONObject jsonObject) {
        JSONArray items = jsonObject.getJSONArray("items");
        //可能会存在图片没有识别结果
        if (Objects.isNull(items)){
            log.info(f.getName() + "没有识别结果");
            return null;
        }
        ResultDataFGKDZ data = new ResultDataFGKDZ();
        data.setFileName(f.getName());
        for (int i = 0;i < items.size();i++){
            JSONObject itemObject = (JSONObject) items.get(i);
            String item = itemObject.getString("item");
            String itemString = itemObject.getString("itemstring");
            setValue(data, item, itemString);
        }
        data.setFieldCount(items.size());
        return data;
    }



    // 非公开定增结果设置
    private static void setValue(ResultDataFGKDZ data, String item, String itemString) {
        switch (item){
            case "发行人":
                if (data.getIssuer() != null ){
                    data.setIssuer(data.getIssuer()+";"+ itemString);
                }else {
                    data.setIssuer(itemString);
                }
                break;
            case "发行价格":
                if (data.getIssuancePrice() != null ){
                    data.setIssuancePrice(data.getIssuancePrice()+";"+ itemString);
                }else {
                    data.setIssuancePrice(itemString);
                }
                break;
            case "获配股票数量":
                if (data.getNumberOfShares() != null ){
                    data.setNumberOfShares(data.getNumberOfShares()+";"+ itemString);
                }else {
                    data.setNumberOfShares(itemString);
                }
                break;
            case "总认购款":
                if (data.getTotalSubscriptionAmount() != null ){
                    data.setTotalSubscriptionAmount(data.getTotalSubscriptionAmount()+";"+ itemString);
                }else {
                    data.setTotalSubscriptionAmount(itemString);
                }
                break;
            case "银行账户名":
                if (data.getBankAccountName() != null ){
                    data.setBankAccountName(data.getBankAccountName()+";"+ itemString);
                }else {
                    data.setBankAccountName(itemString);
                }
                break;
            case "开户行":
                if (data.getBank() != null ){
                    data.setBank(data.getBank()+";"+ itemString);
                }else {
                    data.setBank(itemString);
                }
                break;
            case "银行账号":
                if (data.getBankAccount() != null ){
                    data.setBankAccount(data.getIssuancePrice()+";"+ itemString);
                }else {
                    data.setBankAccount(itemString);
                }
                break;
            case "大额行号":
                if (data.getLargeAmountBankAccount() != null ){
                    data.setLargeAmountBankAccount(data.getLargeAmountBankAccount()+";"+ itemString);
                }else {
                    data.setLargeAmountBankAccount(itemString);
                }
                break;
            case "汇款用途":
                if (data.getPurposeOfRemittance() != null ){
                    data.setPurposeOfRemittance(data.getPurposeOfRemittance()+";"+ itemString);
                }else {
                    data.setPurposeOfRemittance(itemString);
                }
                break;
        }
    }




}
